package cn.seaboot.admin.security.service;

import cn.seaboot.admin.security.bean.SecurityUrl;
import cn.seaboot.admin.security.dao.SecurityUrlDao;
import cn.seaboot.commons.core.CommonUtils;
import cn.seaboot.openapi.base.ControllerInfo;
import cn.seaboot.openapi.base.MethodInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Service
 * 系统地址信息 [t_sys_security_url]
 *
 * @author Mr.css
 * @version 2021-06-16 11:55
 */
@Service
public class SecurityUrlService {

    @Resource
    private SecurityUrlDao securityUrlDao;

    @Resource
    private ApplicationContext applicationContext;

    /**
     * 增
     *
     * @param pojo pojo
     * @return update row's count
     */
    public int insert(SecurityUrl pojo) {
        return securityUrlDao.insert(pojo);
    }

    /**
     * 删
     *
     * @param id id
     * @return update row's count
     */
    public int deleteById(String id) {
        return securityUrlDao.deleteById(id);
    }

    /**
     * 改
     *
     * @param pojo pojo
     * @return update row's count
     */
    public int updateById(SecurityUrl pojo) {
        return securityUrlDao.updateSampleById(pojo);
    }

    /**
     * 查
     *
     * @param id id
     * @return pojo
     */
    public SecurityUrl queryById(String id) {
        return securityUrlDao.selectById(id);
    }

    /**
     * 查列表
     *
     * @param params 参数
     * @return list
     */
    public List<SecurityUrl> queryList(Map<String, Object> params) {
        return securityUrlDao.selectList(params);
    }

    /**
     * 清空表格数据，重新扫描全部接口
     */
    public void rebuildAllApi() {
        securityUrlDao.truncateTable();
        List<SecurityUrl> res = new ArrayList<>();
        Map<String, Object> controllers = applicationContext.getBeansWithAnnotation(Controller.class);
        Map<String, Object> restControllers = applicationContext.getBeansWithAnnotation(RestController.class);
        this.findAllInterface(res, controllers);
        this.findAllInterface(res, restControllers);
        for (SecurityUrl url : res) {
            this.insert(url);
        }
    }

    private void findInterface(List<SecurityUrl> res, ControllerInfo controllerInfo, MethodInfo methodInfo) {
        for (String ctrlPath : controllerInfo.getRequestPath()) {
            for (String methodPath : methodInfo.getRequestPath()) {
                SecurityUrl securityUrl = new SecurityUrl();
                securityUrl.setHashCode(ctrlPath.hashCode());
                securityUrl.setAntPath(ctrlPath + methodPath);
                securityUrl.setDescription(methodInfo.getMethodDescription());
                securityUrl.setDisabled(Boolean.FALSE);
                securityUrl.setRequestMethod(methodInfo.getRequestMethod());
                res.add(securityUrl);
            }
        }
    }

    /**
     * get api form controller map
     *
     * @param controllers controller map
     */
    private void findAllInterface(List<SecurityUrl> res, Map<String, Object> controllers) {
        if (CommonUtils.isNotEmpty(controllers)) {
            for (Object controller : controllers.values()) {
                ControllerInfo controllerInfo = new ControllerInfo(controller.getClass());
                List<MethodInfo> methodInfos = controllerInfo.getMethodInfos();
                if (CommonUtils.isNotEmpty(methodInfos)) {
                    for (MethodInfo methodInfo : methodInfos) {
                        this.findInterface(res, controllerInfo, methodInfo);
                    }
                }
            }
        }
    }
}
